package com.example.seataBusiness.service;

import com.example.seataBusiness.common.enums.RspStatusEnum;
import com.example.seataBusiness.common.response.ObjectResponse;
import com.example.seataBusiness.feign.AccountServiceFeignClient;
import com.example.seataBusiness.feign.OrderServiceFeignClient;
import com.example.seataBusiness.feign.StorageServiceFeignClient;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class BusinessService {

    // 订单服务
    private final OrderServiceFeignClient orderServiceFeignClient;
    // 账户服务
    private final AccountServiceFeignClient accountServiceFeignClient;
    // 库存服务
    private final StorageServiceFeignClient storageServiceFeignClient;

    boolean flag;

    public BusinessService(OrderServiceFeignClient orderServiceFeignClient, AccountServiceFeignClient accountServiceFeignClient, StorageServiceFeignClient storageServiceFeignClient) {
        this.orderServiceFeignClient = orderServiceFeignClient;
        this.accountServiceFeignClient = accountServiceFeignClient;
        this.storageServiceFeignClient = storageServiceFeignClient;
    }

    /**
     * 正常的业务逻辑
     *
     * @param userId        用户ID
     * @param commodityCode 商品编号
     * @param count         购买数量
     * @param orderMoney    订单总金额
     */
    @GlobalTransactional
    public ObjectResponse<Object> handleBusiness(String userId, String commodityCode, Integer count, Double orderMoney) {
        log.info("(正常业务逻辑测试)开始全局事务，XID = " + RootContext.getXID());
        ObjectResponse<Object> response = new ObjectResponse<>();
        // 创建订单
        ObjectResponse<Object> orderResponse = orderServiceFeignClient.createOrder(userId, commodityCode, count, orderMoney);
        // 扣账户金额
        ObjectResponse<Object> accountResponse = accountServiceFeignClient.decreaseAccount(userId, orderMoney);
        // 减库存
        ObjectResponse<Object> storageResponse = storageServiceFeignClient.deduct(commodityCode, count);
        return getObjectResponse(response, orderResponse, accountResponse, storageResponse);
    }

    /**
     * 异常的业务逻辑
     *
     * @param userId        用户ID
     * @param commodityCode 商品编号
     * @param count         购买数量
     * @param orderMoney    订单总金额
     */
    @GlobalTransactional
    public ObjectResponse<Object> handleBusinessExceptiop(String userId, String commodityCode, Integer count, Double orderMoney) {
        log.info("(异常业务逻辑测试)开始全局事务，XID = " + RootContext.getXID());
        ObjectResponse<Object> response = new ObjectResponse<>();
        // 1.创建订单
        ObjectResponse<Object> orderResponse = orderServiceFeignClient.createOrder(userId, commodityCode, count, orderMoney);
        // 2.扣账户金额
        ObjectResponse<Object> accountResponse = accountServiceFeignClient.decreaseAccount(userId, orderMoney);
        // 3.减库存
        ObjectResponse<Object> storageResponse = storageServiceFeignClient.deduct(commodityCode, count);

        // 打开注释测试事务发生异常后，全局回滚功能
        if (!flag) {
            throw new RuntimeException("测试抛异常后，分布式事务回滚！");
        }
        return getObjectResponse(response, orderResponse, accountResponse, storageResponse);
    }

    /**
     * 模块抽取优化
     */
    private ObjectResponse<Object> getObjectResponse(ObjectResponse<Object> response,
                                             ObjectResponse<Object> orderResponse,
                                             ObjectResponse<Object> accountResponse,
                                             ObjectResponse<Object> storageResponse) {
        if (orderResponse.getStatus() != 200 || accountResponse.getStatus() != 200 || storageResponse.getStatus() != 200) {
            response.setStatus(RspStatusEnum.FAIL.getCode());
            response.setMessage(RspStatusEnum.FAIL.getMessage());
            return response;
        }
        response.setStatus(RspStatusEnum.SUCCESS.getCode());
        response.setMessage(RspStatusEnum.SUCCESS.getMessage());
        return response;
    }
}
